home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Overload Trio 2
/
Shareware Overload Trio Volume 2 (Chestnut CD-ROM).ISO
/
dir24
/
jnos110g.zip
/
SESSION.C
< prev
next >
Wrap
C/C++ Source or Header
|
1994-04-17
|
14KB
|
556 lines
/* NOS User Session control
* Copyright 1991 Phil Karn, KA9Q
*
* Mods by PA0GRI
*/
#include "global.h"
#include "config.h"
#include "mbuf.h"
#include "proc.h"
#include "ftpcli.h"
#include "icmp.h"
#include "telnet.h"
#include "tty.h"
#include "session.h"
#include "hardware.h"
#include "socket.h"
#include "cmdparse.h"
#include "rlogin.h"
#include "commands.h"
#include "main.h"
#include "pc.h"
struct session *Sessions;
struct session *Command;
struct session *Current;
struct session *Lastcurr;
extern struct session *Trace;
int Row;
int Morewait;
extern int Numrows;
extern int StatusLines;
char Notval[] = "Not a valid control block\n";
static char Badsess[] = "Invalid session\n";
char TooManySessions[] = "Too many sessions\n";
char *Sestypes[] = {
"Command",
"Telnet",
"FTP",
"AX25",
"Finger",
"Ping",
"NET/ROM",
"Command",
"More",
"Hopcheck",
"Tip",
"PPP PAP",
"Dial",
"Query",
"Cache",
"Rlogin",
"Repeat",
"Look",
"Trace"
};
/* Convert a character string containing a decimal session index number
* into a pointer. If the arg is NULLCHAR, use the current default session.
* If the index is out of range or unused, return NULLSESSION.
*/
struct session *
sessptr(cp)
char *cp;
{
struct session *sp;
unsigned int i;
if(cp == NULLCHAR){
sp = Lastcurr;
} else {
i = (unsigned)atoi(cp);
if(i >= Nsessions)
sp = NULLSESSION;
else
sp = &Sessions[i];
}
if(sp == NULLSESSION || sp->type == FREE)
sp = NULLSESSION;
return sp;
}
/* Select and display sessions */
int
dosession(argc,argv,p)
int argc;
char *argv[];
void *p;
{
struct session *sp;
struct sockaddr fsocket;
int i,k,s;
int r,t;
char *cp,swap;
char *param[3];
sp = (struct session *)p;
if(argc > 1){
if(strncmpi(argv[1],"swap",strlen(argv[1])) == 0) {
if(argc == 2) {
#ifdef EMS
if(SwapMode == EMS_SWAP)
tputs("EMS\n");
else
#endif
#ifdef XMS
if(SwapMode == XMS_SWAP)
tputs("XMS\n");
else
#endif
if(SwapMode == MEM_SWAP)
tputs("Memory\n");
else
tputs("Tmp files\n");
} else {
#ifdef EMS
if(*argv[2] == 'e' || *argv[2] == 'E') {
SwapMode = EMS_SWAP;
} else
#endif
#ifdef XMS
if(*argv[2] == 'x' || *argv[2] == 'X') {
if(!ScreenSizeK)
ScreenSizeK = (ScreenSize / 1024) + 1;
SwapMode = XMS_SWAP;
} else
#endif
if(*argv[2] == 'f' || *argv[2] == 'F') {
SwapMode = FILE_SWAP;
} else {
SwapMode = MEM_SWAP;
}
}
return 0;
}
if((sp = sessptr(argv[1])) == NULLSESSION){
tprintf("Session %s not active\n",argv[1]);
return 1;
}
if(argc == 2){
go(0,NULL,sp);
} else {
switch (*argv[2]) {
case 'f': /* flowmode */
param[0] = argv[2];
param[1] = argv[3];
param[2] = NULL;
setbool(&sp->flowmode,"Set flowmode on/off",argc-2,param);
break;
default:
tprintf("usage:session # [flow [on/off]]\n");
}
}
return 0;
}
tputs(" # S# Sw Type Rcv-Q Snd-Q State Remote socket\n");
for(sp=Sessions; sp < &Sessions[Nsessions];sp++){
if(sp->type == FREE || sp->type == COMMAND || sp->type == TRACESESSION)
continue;
/* Rcv-Q includes output pending at the screen driver */
r = socklen(sp->output,1);
t = 0;
cp = NULLCHAR;
if((s = sp->s) != -1){
i = SOCKSIZE;
/* s = sp->s; */
k = getpeername(s,(char *)&fsocket,&i);
r += socklen(s,0);
t = socklen(s,1);
cp = sockstate(s);
}
#ifdef EMS
if(sp->screen->stype == EMS_SWAP)
swap = 'E';
else
#endif
#ifdef XMS
if(sp->screen->stype == XMS_SWAP)
swap = 'X';
else
#endif
if(sp->screen->stype == FILE_SWAP)
swap = 'F';
else swap = 'M';
tputc((Lastcurr == sp)?'*':' ');
tprintf("%-3u", (unsigned)(sp - Sessions));
tprintf("%-4d%c %-8s%6d%6d %-13s",
s,swap,Sestypes[sp->type],r,t,(cp != NULLCHAR) ? cp : "Limbo!");
if(sp->name != NULLCHAR)
tprintf("%s ",sp->name);
if(sp->s != -1 && k == 0)
tprintf("(%s)",psocket(&fsocket));
tputc('\n');
if(sp->type == FTP && (s = sp->cb.ftp->data) != -1){
/* Display data channel, if any */
i = SOCKSIZE;
k = getpeername(s,(char *)&fsocket,&i);
r = socklen(s,0);
t = socklen(s,1);
cp = sockstate(s);
tprintf(" %-4d %-8s%6d%6d %-13s%s",
s,Sestypes[sp->type],r,t,
(cp != NULLCHAR) ? cp : "Limbo!",
(sp->name != NULLCHAR) ? sp->name : "");
if(k == 0)
tprintf(" (%s)",psocket(&fsocket));
if(tputc('\n') == EOF)
break;
}
if(sp->rfile != NULLCHAR)
tprintf(" Record: %s\n",sp->rfile);
if(sp->ufile != NULLCHAR)
tprintf(" Upload: %s\n",sp->ufile);
}
return 0;
}
/* Resume current session, and wait for it */
int
go(argc,argv,p)
int argc;
char *argv[];
void *p;
{
struct session *sp;
sp = (struct session *)p;
if(sp == NULLSESSION || sp->type == FREE || \
sp->type == COMMAND || sp->type == TRACESESSION)
return 0;
Current = sp;
swapscreen(Command,sp);
#ifdef STATUSWIN
UpdateStatus();
#endif
psignal(sp,0);
return 0;
}
int
doclose(argc,argv,p)
int argc;
char *argv[];
void *p;
{
struct session *sp;
sp = (struct session *)p;
if(argc > 1)
sp = sessptr(argv[1]);
if(sp == NULLSESSION){
tputs(Badsess);
return -1;
}
shutdown(sp->s,1);
if(sp->type == MORE || sp->type == LOOK)
alert(sp->proc,EABORT);
return 0;
}
int
doreset(argc,argv,p)
int argc;
char *argv[];
void *p;
{
struct session *sp;
sp = (struct session *)p;
if(argc > 1)
sp = sessptr(argv[1]);
if(sp == NULLSESSION){
tputs(Badsess);
return -1;
}
/* Unwedge anyone waiting for a domain resolution, etc */
alert(sp->proc,EABORT);
shutdown(sp->s,2);
if(sp->type == FTP)
shutdown(sp->cb.ftp->data,2);
return 0;
}
int
dokick(argc,argv,p)
int argc;
char *argv[];
void *p;
{
struct session *sp;
sp = (struct session *)p;
if(argc > 1)
sp = sessptr(argv[1]);
if(sp == NULLSESSION){
tputs(Badsess);
return -1;
}
sockkick(sp->s);
if(sp->type == FTP)
sockkick(sp->cb.ftp->data);
return 0;
}
struct session *
newsession(name,type,split)
char *name;
int type;
int split;
{
struct session *sp;
int i;
/* Make sure we have enough memory to swap the old session out - WG7J */
if(availmem() < Memthresh/2 + ScreenSize)
return NULLSESSION;
/* Reserve the highest session for Trace, so that
* the F-key session switching works correctly - WG7J
*/
if(type == TRACESESSION) { /* This can only get called once !! */
i=0;
sp=Sessions;
while(i!=Nsessions-1) {
i++;
sp++;
}
} else {
for(i=0,sp=Sessions;i < Nsessions;sp++,i++)
if(sp->type == FREE)
break;
}
if(i == Nsessions)
return NULLSESSION;
sp->curdirs = NULL;
sp->num = i;
sp->type = type;
sp->s = -1;
if(name != NULLCHAR)
sp->name = strdup(name);
sp->proc = Curproc;
/* Create standard input and output sockets. Output is
* translated to local end-of-line by default
*/
if(type != TRACESESSION) {
close_s(Curproc->input);
Curproc->input = sp->input = socket(AF_LOCAL,SOCK_STREAM,0);
seteol(Curproc->input,Eol);
sockmode(Curproc->input,SOCK_BINARY);
close_s(Curproc->output);
Curproc->output = sp->output = socket(AF_LOCAL,SOCK_STREAM,0);
seteol(Curproc->output,Eol);
sockmode(Curproc->output,SOCK_ASCII);
} else
sp->input = sp->output = -1;
#ifdef TRACE
if(type == COMMAND && Trace) {
Trace->input = sp->input;
Trace->output = sp->output;
}
#endif
/* on by default */
sp->ttystate.crnl = sp->ttystate.edit = sp->ttystate.echo = 1;
sp->flowmode = 0; /* Off by default */
sp->row = Numrows - 1 - StatusLines;
sp->morewait = 0;
sp->split = split;
newscreen(sp);
swapscreen(Current,sp);
Current = sp;
#ifdef STATUSWIN
UpdateStatus();
#endif
return sp;
}
void
freesession(sp)
struct session *sp;
{
if(sp == NULLSESSION)
return;
pwait(NULL); /* Wait for any pending output to go */
rflush();
if(sp->proc1 != NULLPROC)
killproc(sp->proc1);
sp->proc1 = NULLPROC;
if(sp->proc2 != NULLPROC)
killproc(sp->proc2);
sp->proc2 = NULLPROC;
free_p(sp->ttystate.line);
sp->ttystate.line = NULLBUF;
if(sp->s != -1)
close_s(sp->s);
if(sp->record != NULLFILE){
fclose(sp->record);
sp->record = NULLFILE;
}
free(sp->rfile);
sp->rfile = NULLCHAR;
if(sp->upload != NULLFILE){
fclose(sp->upload);
sp->upload = NULLFILE;
}
free(sp->ufile);
sp->ufile = NULLCHAR;
free(sp->name);
sp->name = NULLCHAR;
sp->type = FREE;
close_s(sp->input);
sp->input = -1;
sp->proc->input = -1;
close_s(sp->output);
sp->output = -1;
sp->proc->output = -1;
freescreen(sp);
if(Current == sp){
Current = Command;
swapscreen(NULLSESSION,Command);
#ifdef STATUSWIN
UpdateStatus();
#endif
#ifndef LINUX
alert(Display,1);
#endif
}
if(Lastcurr == sp)
Lastcurr = NULLSESSION;
}
#ifdef ALLCMD
/* Control session recording */
int
dorecord(argc,argv,p)
int argc;
char *argv[];
void *p;
{
struct session *sp;
char *mode;
sp = (struct session *)p;
if(sp == NULLSESSION){
tputs("No current session\n");
return 1;
}
if(argc > 1){
if(sp->rfile != NULLCHAR){
fclose(sp->record);
free(sp->rfile);
sp->record = NULLFILE;
sp->rfile = NULLCHAR;
}
/* Open new record file, unless file name is "off", which means
* disable recording
*/
if(strcmp(argv[1],"off") != 0){
if(sockmode(sp->output,-1) == SOCK_ASCII)
mode = APPEND_TEXT;
else
mode = APPEND_BINARY;
if((sp->record = fopen(argv[1],mode)) == NULLFILE)
tprintf("Can't open %s: %s\n",argv[1],sys_errlist[errno]);
else
sp->rfile = strdup(argv[1]);
}
}
if(sp->rfile != NULLCHAR)
tprintf("Recording into %s\n",sp->rfile);
else
tputs("Recording off\n");
return 0;
}
/* Control file transmission */
int
doupload(argc,argv,p)
int argc;
char *argv[];
void *p;
{
register struct session *sp;
sp = (struct session *)p;
if(sp == NULLSESSION){
tputs("No current session\n");
return 1;
}
if(argc < 2){
if(sp->ufile != NULLCHAR)
tprintf("Uploading %s\n",sp->ufile);
else
tputs("Uploading off\n");
return 0;
}
if(strcmp(argv[1],"stop") == 0 && sp->upload != NULLFILE){
/* Abort upload */
fclose(sp->upload);
sp->upload = NULLFILE;
free(sp->ufile);
sp->ufile = NULLCHAR;
killproc(sp->proc2);
sp->proc2 = NULLPROC;
return 0;
}
/* Open upload file */
if((sp->upload = fopen(argv[1],READ_TEXT)) == NULLFILE){
tprintf("Can't read %s: %s\n",argv[1],sys_errlist[errno]);
return 1;
}
sp->ufile = strdup(argv[1]);
/* All set, invoke the upload process */
sp->proc2 = newproc("upload",1024,upload,0,sp,NULL,0);
return 0;
}
/* File uploading task */
void
upload(unused,sp1,p)
int unused;
void *sp1;
void *p;
{
struct session *sp;
int oldf;
char *buf;
sp = (struct session *)sp1;
/* Disable newline buffering for the duration */
oldf = setflush(sp->s,-1);
buf = mallocw(BUFSIZ);
while(fgets(buf,BUFSIZ,sp->upload) != NULLCHAR)
if(usputs(sp->s,buf) == EOF)
break;
free(buf);
usflush(sp->s);
setflush(sp->s,oldf);
fclose(sp->upload);
sp->upload = NULLFILE;
free(sp->ufile);
sp->ufile = NULLCHAR;
sp->proc2 = NULLPROC;
}
#endif /*ALLCMD*/